package org.meandslava.calc.utils;

import java.text.Format;
import java.util.ArrayList;
import java.util.List;

import org.meandslava.calc.R;

import android.content.res.Resources;
import android.text.Editable;

public class Expression extends Term {
	private List<Integer> arithmetic = new ArrayList<Integer>();
	private List<Term> terms = new ArrayList<Term>();
	private Resources resources;

	private static int SYMBOL_ZERO;
	private static int SYMBOL_ONE;
	private static int SYMBOL_TWO;
	private static int SYMBOL_THREE;
	private static int SYMBOL_FOUR;
	private static int SYMBOL_FIVE;
	private static int SYMBOL_SIX;
	private static int SYMBOL_SEVEN;
	private static int SYMBOL_EIGHT;
	private static int SYMBOL_NINE;
	private static int SYMBOL_POINT;
	private static int SYMBOL_PLUS;
	private static int SYMBOL_MINUS;
	private static int SYMBOL_MULTIPLY;
	private static int SYMBOL_DIVIDE;
	private static int SYMBOL_OPEN_BRACKET;
	private static int SYMBOL_CLOSE_BRACKET;
	
	public Expression(Resources resources){
		this.resources = resources;
		/*
		SYMBOL_ZERO = resources.getInteger(R.integer.symbol_zero);
		SYMBOL_ONE = resources.getInteger(R.integer.symbol_one);
		SYMBOL_TWO = resources.getInteger(R.integer.symbol_two);
		SYMBOL_THREE = resources.getInteger(R.integer.symbol_three);
		SYMBOL_FOUR = resources.getInteger(R.integer.symbol_four);
		SYMBOL_FIVE = resources.getInteger(R.integer.symbol_five);
		SYMBOL_SIX = resources.getInteger(R.integer.symbol_six);
		SYMBOL_SEVEN = resources.getInteger(R.integer.symbol_seven);
		SYMBOL_EIGHT = resources.getInteger(R.integer.symbol_eight);
		SYMBOL_NINE = resources.getInteger(R.integer.symbol_nine);
		SYMBOL_POINT = resources.getInteger(R.integer.symbol_point);
		SYMBOL_PLUS = resources.getInteger(R.integer.symbol_plus);
		SYMBOL_MINUS = resources.getInteger(R.integer.symbol_minus);
		SYMBOL_MULTIPLY = resources.getInteger(R.integer.symbol_multiply);
		SYMBOL_DIVIDE = resources.getInteger(R.integer.symbol_divide);
		SYMBOL_OPEN_BRACKET = resources.getInteger(R.integer.symbol_open_bracket);
		SYMBOL_CLOSE_BRACKET = resources.getInteger(R.integer.symbol_close_bracket);
		//SYMBOL_ONE = resources.getInteger(R.integer.symbol_one);
		
		*/
	}
	
	public void addSymbol(int symbol){
		/*if((symbol==SYMBOL_ZERO) || 
		   (symbol==SYMBOL_ONE) || 
		   (symbol==SYMBOL_TWO) || 
		   (symbol==SYMBOL_THREE) || 
		   (symbol==SYMBOL_FOUR) || 
		   (symbol==SYMBOL_FIVE) || 
		   (symbol==SYMBOL_SIX) || 
		   (symbol==SYMBOL_SEVEN) || 
		   (symbol==SYMBOL_EIGHT) || 
		   (symbol==SYMBOL_NINE)){
			applyDigit(symbol);
	    	return;
		}
		if(symbol == SYMBOL_POINT){
			applyPoint();
			return;
		}*/
		applyArithmetic(symbol);
	}

	private void applyArithmetic(int symbol) {
		if(arithmetic.size() < terms.size()){
			arithmetic.add(symbol);
		}else{
			if(arithmetic.size() != 0){
				arithmetic.set(arithmetic.size()-1, symbol);
			}
		}
	}

	@Override
	public double getResult() {
		if(terms.size() == 0){
			return 0;
		}
		
		Term tmp;
		tmp = terms.get(0);
		for(int i=1;i<terms.size();i++){
			tmp = combine(tmp, terms.get(i), arithmetic.get(i-1));
		}
		return tmp.getResult();
	}
	
	private static Term combine(Term arg1, Term arg2, int arithmetic){
		/*if(arithmetic == SYMBOL_PLUS){
			return new FixedNumber(arg1.getResult() + arg2.getResult());
		}else if(arithmetic == SYMBOL_MINUS){
			return new FixedNumber(arg1.getResult() - arg2.getResult());
		}else if(arithmetic == SYMBOL_MULTIPLY){
			return new FixedNumber(arg1.getResult() * arg2.getResult());
		}else if(arithmetic == SYMBOL_DIVIDE){
			return new FixedNumber(arg1.getResult() / arg2.getResult());
		}*/
		return arg1;
	}
	
	@Override
	public void applyDigit(int digit) {
		if(terms.size() == 0 || arithmetic.size() == terms.size()){
			terms.add(new FixedNumber(digit));
			return;
		}
		
		Term lastTerm = terms.get(terms.size() -1);
		lastTerm.applyDigit(digit);
	}

	@Override
	public void applyPoint() {
		Term lastTerm;
		if(terms.size() == 0 || arithmetic.size() == terms.size()){
			lastTerm = new FixedNumber(0);
			terms.add(lastTerm);
		}else{
			lastTerm = terms.get(terms.size() -1);
		}
		lastTerm.applyPoint();
	}

	public String getStringResult() {
		double result = getResult();
		String out = format.format(result);
		
		return out;
	}
	
	@Override
	public void writeExpression(Editable editable){
		Term t;
		if(terms.size() == 0){
			return;
		}
		for(int i=0; i<terms.size()-1; i++){
			t = terms.get(i);
			if(t instanceof Expression){
				editable.append('(');
				t.writeExpression(editable);
				editable.append(')');
			}else{
				t.writeExpression(editable);
			}
			
			writeArithmetic(arithmetic.get(i), editable);
		}
		terms.get(terms.size() - 1).writeExpression(editable);
		if(arithmetic.size() == terms.size()){
			writeArithmetic(arithmetic.get(arithmetic.size() - 1), editable);
		}
	}
	
	private void writeArithmetic(int arithmetic, Editable editable){
		/*if(arithmetic == SYMBOL_PLUS){
			editable.append('+');
		}else if(arithmetic == SYMBOL_MINUS){
			editable.append('-');
		}else if(arithmetic == SYMBOL_MULTIPLY){
			editable.append('*');
		}else if(arithmetic == SYMBOL_DIVIDE){
			editable.append('/');
		}*/
	}

	@Override
	public boolean back() {
		if(terms.size() == 0){
			return true;
		}
		if(arithmetic.size() == terms.size()){
			arithmetic.remove(arithmetic.size()-1);
		}else{
			Term t = terms.get(terms.size()-1);
			if(t.back()){
				terms.remove(t);
				if(terms.size() == 0){
					return true;
				}
			}
		}
		return false;
	}
}
